package com.example.tccdemo.service;

import com.example.tccdemo.db131.dao.AccountAMapper;
import com.example.tccdemo.db131.dao.PaymentMsgMapper;
import com.example.tccdemo.db131.model.AccountA;
import com.example.tccdemo.db131.model.PaymentMsg;
import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.client.producer.SendStatus;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.exception.RemotingException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;

/**
 * @describte:操作131数据库，进行支付操作
 * @program:distribute-transaction
 * @author:zhengdp
 * @create:2021-09-26 22:06:26
 **/
@Service
public class PaymentService {

    @Autowired
    private AccountAMapper accountAMapper;

    @Autowired
    private PaymentMsgMapper paymentMsgMapper;

    /**
     *  支付接口
     * @param userId 用户Id
     * @param orderId 订单Id
     * @param amount 订单金额
     * @return 1:用户不存在  2：余额不足 0:成功
     */
    @Transactional(transactionManager = "tm131")
    public int payment(int userId, int orderId, BigDecimal amount){
        // 检索出用户账户
        AccountA accountA = accountAMapper.selectByPrimaryKey(userId);
        if(accountA == null){
            return 1;
        }
        // 判断余额是否充足
        if(accountA.getBalance().compareTo(amount) < 0){
            return 2;
        }
        // 扣减余额
        accountA.setBalance(accountA.getBalance().subtract(amount));
        accountAMapper.updateByPrimaryKey(accountA);
        // 支付完毕（余额扣减完毕后），创建一条消息
        PaymentMsg paymentMsg = new PaymentMsg();
        paymentMsg.setOrderId(orderId);
        paymentMsg.setStatus(0);  // 未发送
        paymentMsg.setFalureCnt(0); // 失败次数
        paymentMsg.setCreateTime(new Date());
        paymentMsg.setCreateUser(userId);
        paymentMsg.setUpdateTime(new Date());
        paymentMsg.setUpdateUser(userId);
        paymentMsgMapper.insertSelective(paymentMsg);
        return 0;
    }

    @Autowired
    private DefaultMQProducer producer;

    /**
     * 将消息放入MQ中
     * @param userId
     * @param orderId
     * @param amount
     * @return
     */
    @Transactional(transactionManager = "tm131",rollbackFor = Exception.class)
    public int paymentMQ(int userId, int orderId, BigDecimal amount) throws Exception {
        // 检索出用户账户
        AccountA accountA = accountAMapper.selectByPrimaryKey(userId);
        if(accountA == null){
            return 1;
        }
        // 判断余额是否充足
        if(accountA.getBalance().compareTo(amount) < 0){
            return 2;
        }
        // 扣减余额
        accountA.setBalance(accountA.getBalance().subtract(amount));
        accountAMapper.updateByPrimaryKey(accountA);
        // 支付完毕（余额扣减完毕后），创建一条消息
        Message message = new Message();
        message.setTopic("payment");
        message.setKeys(orderId+"");
        message.setBody("订单已支付".getBytes());
        try {
            SendResult result = producer.send(message);
            if(result.getSendStatus()== SendStatus.SEND_OK){
                return 0;
            }else{
                // 发送失败，前面账户扣减的操作应该回滚
                // 账户扣减和发送消息的操作应该是原子性的
                throw new Exception("消息发送失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }
}
